<script setup lang="ts">
import { unwrapApiBody, type ApiResponse } from '../../../utils/http/factory'
import {
  formatOccurredOnDisplay,
  occurredOnToIsoAttr,
} from '../../../utils/timeline-datetime'

definePageMeta({
  layout: 'public',
  title: '时光机',
})

const route = useRoute()
const router = useRouter()
const slug = computed(() => route.params.publicSlug as string)

function parsePage(raw: unknown): number {
  const n =
    typeof raw === 'string'
      ? Number.parseInt(raw, 10)
      : typeof raw === 'number'
        ? raw
        : Number.NaN
  if (!Number.isFinite(n) || n < 1) {
    return 1
  }
  return Math.floor(n)
}

const page = ref(parsePage(route.query.page))

watch(
  () => [route.params.publicSlug, route.query.page] as const,
  () => {
    page.value = parsePage(route.query.page)
  },
)

type PublicTimelineItem = {
  id?: number
  title?: string | null
  occurredOn?: Date | string | null
  linkUrl?: string | null
  bodyMarkdown?: string | null
}

type Payload = {
  items: PublicTimelineItem[]
  total: number
  page: number
  pageSize: number
}

function timelineItemKey(e: PublicTimelineItem, i: number): string | number {
  return e.id ?? i
}

function onPageChange(p: number) {
  page.value = p
  const query: Record<string, string | string[] | undefined> = { ...route.query }
  if (p > 1) {
    query.page = String(p)
  }
  else {
    delete query.page
  }
  void router.replace({ query })
}

const { data, pending, error } = await useAsyncData(
  () => `public-timeline-${slug.value}-${page.value}`,
  async () => {
    const base = `/api/public/profile/${encodeURIComponent(slug.value)}/timeline`
    const url = page.value > 1 ? `${base}?page=${page.value}` : base
    const res = await $fetch<ApiResponse<Payload>>(url)
    return unwrapApiBody(res)
  },
  { watch: [slug, page] },
)
</script>

<template>
  <UContainer class="py-8 lg:py-10 max-w-6xl">
    <div v-if="pending && !data" class="text-muted py-10">
      加载中…
    </div>
    <UAlert
      v-else-if="error && !data"
      color="error"
      title="无法加载时光机"
      class="my-6"
    />
    <template v-else-if="data">
      <UEmpty
        v-if="data.total === 0"
        title="暂无时光机记录"
        description="站主尚未发布任何公开动态。"
      />
      <template v-else>
        <h2 class="text-xs font-semibold uppercase tracking-wider text-muted mb-4">
          时光机
        </h2>
        <ul class="relative space-y-0">
          <li
            v-for="(e, i) in data.items"
            :key="timelineItemKey(e, i)"
            class="relative flex gap-4 pb-6 pl-1 last:pb-0"
          >
            <div
              v-if="i < data.items.length - 1"
              class="absolute left-[11px] top-5 bottom-0 w-px bg-default"
              aria-hidden="true"
            />
            <div class="relative z-[1] flex shrink-0 flex-col items-center pt-0.5">
              <span class="size-2.5 rounded-full bg-primary ring-4 ring-primary/15" />
            </div>
            <article
              class="min-w-0 flex-1 rounded-xl border border-default bg-elevated/25 px-5 py-5 shadow-sm sm:px-6"
            >
              <div class="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between sm:gap-4">
                <time
                  class="shrink-0 text-xs font-medium tabular-nums text-muted sm:order-2 sm:text-right"
                  :datetime="e.occurredOn ? occurredOnToIsoAttr(e.occurredOn) : undefined"
                >{{ formatOccurredOnDisplay(e.occurredOn ?? '') }}</time>
                <h3 class="text-pretty text-lg font-semibold text-highlighted sm:order-1 sm:min-w-0 sm:flex-1">
                  {{ e.title }}
                </h3>
              </div>
              <p
                v-if="e.bodyMarkdown && e.bodyMarkdown.trim()"
                class="mt-4 whitespace-pre-wrap border-t border-default/60 pt-4 text-sm leading-relaxed text-default text-pretty"
              >
                {{ e.bodyMarkdown }}
              </p>
              <a
                v-if="e.linkUrl"
                :href="e.linkUrl"
                target="_blank"
                rel="noopener noreferrer"
                class="mt-4 inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline"
              >
                <span>打开链接</span>
                <UIcon name="i-lucide-external-link" class="size-3.5 opacity-80" />
              </a>
            </article>
          </li>
        </ul>
        <div v-if="data.total > 10" class="flex justify-end mt-6">
          <UPagination
            :page="page"
            :total="data.total"
            items-per-page="10"
            size="sm"
            @update:page="onPageChange"
          />
        </div>
      </template>
    </template>
  </UContainer>
</template>
